class Solution {
public:
    ListNode* cut(ListNode* h,int n){
        while(h && --n){
            h = h->next;
        }
        if(!h) return NULL;
        
        auto p = h->next;
        h->next = NULL;
        return p;
    }
    
    ListNode* merge(ListNode* h1,ListNode* h2){
        if(!h1) return h2;
        if(!h2) return h1;
        ListNode* dHead = new ListNode(0);
        ListNode* tail = dHead;
        while(h1 && h2){
            if(h1->val <= h2->val){
                tail->next = h1;
                h1 = h1->next;
            }else{
                tail->next = h2;
                h2 = h2->next;
            }
            tail = tail->next;
        }
        tail->next = h1? h1 : h2;
        return dHead->next;
    }
    
    ListNode* sortList(ListNode* head) {
        if(head == NULL) return NULL;
        ListNode* dHead = new ListNode(0);
        dHead->next = head;
        ListNode* h = dHead;
        int size = 0;
        while(h){
            size++;
            h = h->next;
        }
        
        for(int i = 1;i < size;i *= 2){
            auto cur = dHead->next;
            auto tail = dHead;
            
            while(cur){
                auto left = cur;
                auto right = cut(left,i);
                cur = cut(right,i);
                
                tail->next = merge(left,right);
                
                while(tail->next){
                    tail = tail->next;
                }
            }
            
        }
        return dHead->next; 
    }
};
